﻿/********
* 
* 
*  Description:
*  Create By kain.hong at 11/16/2010 4:28:02 PM
*  
*
*  Revision History:
*  Date                  Who                 What
*  
* 
*/
#region namespace

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

#endregion


namespace Cherry.Agile.Framework
{
    /// <summary>
    /// 解析字符格式
    /// </summary>
    public class TemplateStringParser
    {
        private static readonly Regex escapedParameterReferenceRegex = new Regex(@"\\\{(?<parameter>\d+)}");
        private Dictionary<string, string> parameters = new Dictionary<string, string>();

        /// <summary>
        /// 检查字符是否匹配
        /// </summary>
        /// <param name="template">模板字符串</param>
        /// <param name="target">目标字符</param>
        /// <returns>匹配是否正确</returns>
        public static bool IsMatch(string template, string target)
        {
            Regex templateRegex = Translate(template);
            return templateRegex.IsMatch(target);
        }

        /// <summary>
        /// 匹配字符
        /// </summary>
        /// <param name="template">模板字符串</param>
        /// <param name="target">目标字符</param>
        /// <returns><see cref="System.Text.RegularExpressions.Match"/></returns>
        public static Match Match(string template, string target)
        {
            Regex templateRegex = Translate(template);
            return templateRegex.Match(target);
        }

        internal static Regex Translate(string template)
        {
            return new TemplateStringParser().DoTranslate(template);
        }

        private Regex DoTranslate(string template)
        {
            template = Regex.Escape(template);
            template = escapedParameterReferenceRegex.Replace(template, this.ReplaceParameterReference);

            return new Regex(template);
        }

        private string ReplaceParameterReference(Match match)
        {
            string parameter = match.Groups["parameter"].Value;

            if (this.parameters.ContainsKey(parameter))
            {
                return string.Format(@"\k<param{0}>", parameter);
            }
            else
            {
                this.parameters.Add(parameter, parameter);
                return string.Format(@"(?<param{0}>.*)", parameter);
            }
        }
    }
}
